package com.sniff.atp.provider;

/**
 * @BelongsProject: sniff-atp
 * @Author: ljj
 * @CreateTime: 2022/11/9 17:00
 * @Description:
 * @Version: 1.0
 */

import com.alibaba.fastjson2.JSONArray;
import com.github.crab2died.ExcelUtils;
import com.sniff.atp.utils.FileUtil;
import com.sniff.atp.utils.JsonUtil;
import org.testng.annotations.DataProvider;

import java.io.*;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class ParamProvider {
    /**
     *  使用方法 _testNg的方法上加如下注解
     *
     * @CsvDataFile("testcase/test2.csv")
     * @Test(dataProvider=ParamProvider.DEFAULT_PROVIDER,dataProviderClass=ParamProvider.class)
     *  public void test1(String field,String dimension,String isLimit,String dayOffSet,String description){}
     *
     *  对应的文件为:testcase/csvDemo.csv
     *
     *  CSV文件中的表头列需要与注解的方法传入参数一一对应
     *
     */
    public final static String OST_PROVIDER = "ostParamProvider";

    /**
     * 支持csv/json/txt/excel等多种文件
     * @param method
     * @return
     */
    @DataProvider(name = OST_PROVIDER)
    public static Object[][] prepareData(Method method) {
        OstDataFile ostDataFile = method.getAnnotation(OstDataFile.class);

        if (null == ostDataFile) {
            throw new IllegalArgumentException(OST_PROVIDER + " must use together with @ParamProvider.");
        }
        if ("".equals(ostDataFile.value())) {
            throw new IllegalArgumentException("filePath can not be null.");
        }

        String directory = "src/main/resources/" +ostDataFile.value();
        String last = ostDataFile.value().split("\\.")[1];
        List<Object[]> dataList = null;
        Object[][] results = null;
        int[] indices = ostDataFile.indices();

        try {
            if ("csv".equals(last)){
                dataList = new ArrayList<>(FileUtil.readCsvToListArray(directory));
            }
            if ("xlsx".equals(last)|"xls".equals(last)) {
                dataList = new ArrayList<>();
                List<List<String>> lists = ExcelUtils.getInstance().readExcel2List(directory, 1);
                for (List<String> list : lists) {
                    Object[] rowcell = list.toArray();
                    dataList.add(rowcell);
                }
            }
            if ("json".equals(last)|"txt".equals(last)|"text".equals(last)) {
                String jsonStr = FileUtil.readFileToString(directory);
                dataList = convertObjectList(jsonStr);
            }
            results = getResData(indices,dataList);
        }catch (Exception e){
            e.printStackTrace();
        }
        return results;
    }

    /**
     * 获取执行数据
     * @param indices
     * @param list
     * @return
     */
    private static Object[][] getResData(int[] indices,List<Object[]> list){
        Object[][] results = null;
        if (indices.length > 0) {
            indices = arrayUnique(indices);
            results = new Object[indices.length][];
            for (int i = 0; i < indices.length; i++) {
                if (indices[i] <= 0) {
                    continue;
                }
                results[i] = list.get(indices[i] - 1);
            }
        } else {
            results = new Object[list.size()][];
            for (int i = 0; i < list.size(); i++) {
                results[i] = list.get(i);
            }
        }return results;
    }
    /**
     * 将json类型数组字符串转变为List<Object[]>
     * @param jsonStr
     * @return
     */
    public static List<Object[]> convertObjectList(String jsonStr) {
        JSONArray jsonArray = JsonUtil.strToJSONArray(jsonStr);
        List<Object[]> jsonList = new ArrayList<>();
        for (int i=0;i<jsonArray.size();i++){
            Map<String, String> map1 = JsonUtil.jsoStr2Map(jsonArray.getJSONObject(i).toString());
            for (String key:map1.keySet()){
                map1.replace(key,String.valueOf(map1.get(key)));
            }
            List<String> stringList = new ArrayList<>(map1.values());
            jsonList.add(stringList.toArray());
        }
        return jsonList;
    }
    /**
     *读取文件内容转变为utf-8编码
     * @param source
     * @param sourceCharset
     * @return
     */
    private static String[] charsetConvert(String[] source,String sourceCharset){
        String[] target = new String[source.length];
        for(int i=0;i<source.length;i++){
            try {
                target[i] =  new String(source[i].getBytes(sourceCharset), StandardCharsets.UTF_8);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return target;
    }
    /**
     * 数组去重复
     * @param indices
     * @return
     */
    private static int[] arrayUnique(int[] indices) {
        Set<Integer> set = new HashSet<Integer>();
        for (int index : indices) {
            set.add(index);
        }
        int[] arrays = new int[set.size()];
        int count = 0;
        for (Integer integer : set) {
            arrays[count] = integer;
            count++;
        }
        return arrays;
    }
}
